
-- 宝石消除判定(获取当前位置的宝石横竖数量)
function Judge_Puz(maps, itype, row, col)
    -- 从左到右
    local lleft = col
    local lright = col
    local lup = row
    local ldown = row
    local icol = col
    local irow = row
    local cgem = nil 
    while 1 do
        icol = icol - 1
        if icol < 0 then
            break
        end
        
        cgem = maps[getIndex(row, icol)]
        if cgem == nil or cgem.tpe ~= itype or cgem:onIsPuzGoBomss() then
            break
        end
        lleft = icol
    end
    
    while 1 do
        icol = icol + 1
        if icol >= Gems_Cols then
            break
        end
        cgem = maps[getIndex(row, icol)]
        if cgem == nil or cgem.tpe ~= itype or cgem:onIsPuzGoBomss() then
            break
        end
        lright = icol
    end
        
    -- 从上到下
    while 1 do
        irow = irow - 1
        if irow < 0 then
            break
        end
        cgem = maps[getIndex(irow, col)]
        if cgem == nil or cgem.tpe ~= itype or cgem:onIsPuzGoBomss() then
            break
        end
        lup = irow
    end
    
    while 1 do
        irow = irow + 1
        if irow >= Gems_Rows then
            break
        end
        cgem = maps[getIndex(irow, col)]
        if cgem == nil or cgem.tpe ~= itype or cgem:onIsPuzGoBomss() then
            break
        end
        ldown = irow
    end
        
    return lleft, lright, lup, ldown
end


    
-- 判断一定宝石是否能进行消除
function has_Puz_Gem(temp_maps, tpe, row, col, key)
    local nleft, nright, nup, ndown = Judge_Puz(temp_maps, tpe, row, col)
	--print(nleft, nright, nup, ndown)
    local has = false
    local rvalue = {}
    if nright - nleft >= Puz_Number or ndown - nup >= Puz_Number then
        has = true
        
        -- 消除的宝石
        local obj = {
            key = key,
            row = row,
            col = col,
            left = nleft,
            right = nright,
            up = nup,
            down = ndown,
            delgems = {},
            tpe = tpe,
        }
        
        -- 生成消除的宝石列表
        obj.delgems = {}
        if obj.right - obj.left >= Puz_Number then
            itype = nil
            i = obj.left
            while i <= obj.right do
                table.insert(obj.delgems, getIndex(obj.row, i))
                i = i + 1
            end
        end
    
        if obj.down - obj.up >= Puz_Number then
            itype = nil
            i = obj.up
            while i <= obj.down do
                table.insert(obj.delgems, getIndex(i, obj.col))
                i = i + 1
            end
        end
        
        table.insert(rvalue, obj)
    end
    
    -- 生成删除的宝石位置
    return has, rvalue
end

-- 判断一定宝石是否能进行消除::连续相邻
function AddSameType(temp_maps, openlist, closelist, gem1, row, col)
    local gem2 = temp_maps[getIndex(row, col)]
    if row >= Gems_Rows or col >= Gems_Cols or row < 0 or col < 0  or gem2 == nil then
        return false
    end
    
    if not gem1.isMoved and not gem2.isMoved and gem1.tpe == gem2.tpe then
        for k, _cgemIdx in pairs(closelist) do
            if _cgemIdx == getIndex(gem2.row, gem2.col) then
                return false
            end
        end
        -- 不存在关闭列表中则添加
        table.insert(openlist, gem2)
        return true
    end
    return false
end

function has_Puz_GemCon(temp_maps, cgem)
    local has = false
    local rvalue = {}
    
    -- 利用队列进行判定,如果当前判定宝石周围有连续的,则添加周围宝石至开放队形中
    -- 把判定宝石添加至开放队列中,并且添加至连续队列中,
    -- 1.从队列中找出得到一个宝石,查看宝石周围是否有连续的,并且从开放队列中删除,添加至连续队列中
    -- 2.有则把它们添加至开放队列中,并且添加至连续队列中,循环1
    -- 3.没有则从队列中删除
    
    local openlist = {}
    local closelist = {}
    
    
        
    local obj = {
        row = cgem.row,
        col = cgem.col,
        delgems = {},
        tpe = cgem.tpe,
    }
    
    table.insert(openlist, cgem)
    local vvvs = 0
    while #openlist > 0 do
        local _lcut = #openlist
        local _cgem = openlist[0]
        --print("1",#openlist)
        for k, _ocgem in pairs(openlist) do
            _cgem = _ocgem
            table.remove(openlist, k)
            break
        end
        --print("2",#openlist)
        table.insert(closelist, getIndex(_cgem.row, _cgem.col))
        -- 判断相连的是否是相同宝石,是则添加
        AddSameType(temp_maps, openlist, closelist, cgem, _cgem.row + 1, _cgem.col)
        AddSameType(temp_maps, openlist, closelist, cgem, _cgem.row - 1, _cgem.col)
        AddSameType(temp_maps, openlist, closelist, cgem, _cgem.row, _cgem.col + 1)
        AddSameType(temp_maps, openlist, closelist, cgem, _cgem.row, _cgem.col - 1)
        --print("3",#openlist)
        
        vvvs = vvvs + 1
    end
    --print("hasg:",vvvs)
    
    if #closelist > 0 then
        has = true
    end
    
    obj.delgems = closelist
    table.insert(rvalue, obj)
    
    return has, obj
end


-- 两个宝石是否可以形成消除
function has_Puz_Gems(_gemTable, gem1, gem2)
    if gem1 == nil or gem2 == nil then
        return
    end
    
    -- 成直线3个以上相同宝石为可消除
    -- 搜索-生成一个判定用的临时表
    local temp_maps = {}
    for c=0,Gems_Cols-1 do
        for r=0,Gems_Rows-1 do
            local idx = getIndex(r,c)
            if _gemTable[idx] ~= nil then
                temp_maps[idx] = _gemTable[idx]
            else
                temp_maps[idx] = nil
            end
        end
    end
    -- 先交换
    temp_maps[getIndex(gem1.row, gem1.col)] = gem2
    temp_maps[getIndex(gem2.row, gem2.col)] = gem1
    -- 两个位置分别判定
    local has = false
    local rvalue = {}
    local has1, rvalue1 = has_Puz_Gem(temp_maps, gem2.tpe, gem1.row, gem1.col, gem2.key)
    local has2, rvalue2 = has_Puz_Gem(temp_maps, gem1.tpe, gem2.row, gem2.col, gem1.key)
    if has1 or has2 then
        has = true
    end
    for k, obj in pairs(rvalue1) do
        table.insert(rvalue, obj)
    end
    for k, obj in pairs(rvalue2) do
        table.insert(rvalue, obj)
    end
    return has, rvalue
end




-- 判断位置是否有宝石((墙边也算有宝石::没有则返回true
function notHasGems(_gemTable, row, col)
    if row < Gems_Rows and col < Gems_Cols and row >= 0 and col >= 0 and _gemTable[getIndex(row, col)] == nil then
        return true
    end
    return false
end
-- 判断四周是否有空位
function on_PickBizz(_gemTable, cgem)
    --print("bizz",cgem.row,cgem.col)
    local hu = notHasGems(_gemTable, cgem.row - 1, cgem.col)
    local hd = notHasGems(_gemTable, cgem.row + 1, cgem.col)
    local hl = notHasGems(_gemTable, cgem.row, cgem.col - 1)
    local hr = notHasGems(_gemTable, cgem.row, cgem.col + 1)
    if hl or hr or hu or hd then
        return true
    end
    return false
end




-- 方法用途：检测2个物体是否碰撞   
-- 参数object1：物体1   
-- 参数object1：物体2   
-- 参数overlap：可重叠的区域值   
-- 返回布尔值：碰撞返回true，不碰撞返回false   
function CheckIntersect(object1, object2, overlap)
    local obj1x = object1.x - gemSize / 2
    local obj1y = object1.y-- - gemSize / 2
    local obj2x = object2.x - gemSize / 2
    local obj2y = object2.y-- - gemSize / 2
    --     x-轴                      x-轴   
    --   A1------>B1 C1              A2------>B2 C2   
    --   +--------+   ^              +--------+   ^   
    --   | object1|   | y-轴         | object2|   | y-轴   
    --   |        |   |              |        |   |   
    --   +--------+  D1              +--------+  D2   
    --   看图可知两物体各4个点的位置   
    local A1 = obj1x + overlap
    local B1 = obj1x + object1.width - overlap
    local C1 = obj1y + overlap
    local D1 = obj1y + object1.height - overlap
    
    local A2 = obj2x + overlap
    local B2 = obj2x + object2.width - overlap
    local C2 = obj2y + overlap
    local D2 = obj2y + object2.width - overlap
    --print("n",A1,B1,C1,D1,"\n",A2,B2,C2,D2)
    -- 假如他们在x-轴重叠   
    if (A1 >= A2 and A1 <= B2) or (B1 >= A2 and B1 <= B2) then
        -- 判断y-轴重叠   
        if (C1 >= C2 and C1 <= D2) or (D1 >= C2 and D1 <= D2) then
            -- 碰撞   
            --print("cin",A1,B1,C1,D1,A2,B2,C2,D2)
            return true
        end
    end
    
    return false
end




